import { Injectable } from '@nestjs/common';
import { Repository, Like } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entity/user.entity';
import { Group, GroupMap } from '../group/entity/group.entity';
import { createWriteStream } from 'fs';
import { join } from 'path';
import { RCode } from 'src/common/constant/rcode';
import { GroupMessage } from '../group/entity/groupMessage.entity';
import { UserMap } from '../friend/entity/friend.entity';
import { FriendMessage } from '../friend/entity/friendMessage.entity';
import { nameVerify, passwordVerify } from 'src/common/tool/utils';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Group)
    private readonly groupRepository: Repository<Group>,
    @InjectRepository(GroupMap)
    private readonly groupUserRepository: Repository<GroupMap>,
    @InjectRepository(GroupMessage)
    private readonly groupMessageRepository: Repository<GroupMessage>,
    @InjectRepository(UserMap)
    private readonly friendRepository: Repository<UserMap>,
    @InjectRepository(FriendMessage)
    private readonly friendMessageRepository: Repository<FriendMessage>,
  ) {}

  async getUser(userId: string) {
    try {
      let data;
      if (userId) {
        data = await this.userRepository.findOne({
          where: { userId: userId },
        });
        let friends = await this.friendRepository.find({
          where: { userId: userId },
        });
        return {
          msg: '获取用户成功',
          data: {
            ...data,
            friends: friends ? friends : [],
          },
        };
      }
    } catch (e) {
      return { code: RCode.ERROR, msg: '获取用户失败', data: e };
    }
  }

  async getUserFirends(userId: string) {
    try {
      if (userId) {
        const friendRelations = await this.friendRepository.find({
          where: { userId: userId },
        });
        let friendIds = [];
        let friends = [];
        if (friendRelations) {
          // 朋友ids
          friendIds = friendRelations.map(data => {
            return data.friendId;
          });
          friends = await this.userRepository.findByIds(friendIds);
        }
        return {
          msg: '获取用户好友成功',
          data: {
            friends: friends ? friends : [],
          },
        };
      }
    } catch (e) {
      return { code: RCode.ERROR, msg: '获取用户好友失败', data: e };
    }
  }

  async getRoomMessages(userId: string, friendId: string) {
    try {
      let messages = await this.friendMessageRepository
        .createQueryBuilder('friendMessage')
        .orderBy('friendMessage.time', 'DESC')
        .where(
          'friendMessage.userId = :userId AND friendMessage.friendId = :friendId',
          { userId: userId, friendId: friendId },
        )
        .orWhere(
          'friendMessage.userId = :friendId AND friendMessage.friendId = :userId',
          { userId: userId, friendId: friendId },
        )
        .getMany();
      // .take(30)
      messages = messages.reverse();
      return { msg: '获取用户成功', data: messages };
    } catch (e) {
      return { code: RCode.ERROR, msg: '获取用户失败', data: e };
    }
  }

  async userAcceptInvite(userId: string, friendId: string) {
    try {
      const isUser = await this.userRepository.findOne({ userId: userId });
      if (isUser) {
        if (friendId && userId) {
          if (userId === friendId) {
            return {
              code: RCode.FAIL,
              msg: '不能添加自己为好友',
              data: '',
            };
          }

          const relation0 = await this.friendRepository.findOne({
            userId: userId,
          });

          console.log('找到的是', relation0);

          if (relation0) {
            return {
              code: RCode.FAIL,
              msg: 'ta已经有好友了哟~',
              data: '',
            };
          }

          const relation1 = await this.friendRepository.findOne({
            userId: userId,
            friendId: friendId,
          });
          const relation2 = await this.friendRepository.findOne({
            userId: friendId,
            friendId: userId,
          });

          if (relation1 || relation2) {
            return {
              code: RCode.FAIL,
              msg: '已经有该好友',
              data: '',
            };
          }

          const friend = await this.userRepository.findOne({
            userId: friendId,
          });
          console.log(friendId);
          const user = await this.userRepository.findOne({ userId: userId });
          if (!friend) {
            return {
              code: RCode.FAIL,
              msg: '该好友不存在',
              data: '',
            };
          }

          const userFriendData = new UserMap();
          userFriendData.userId = userId;
          userFriendData.friendId = friendId;

          const friendFriendData = new UserMap();
          friendFriendData.userId = friendId;
          friendFriendData.friendId = userId;

          // 双方都添加好友 并存入数据库
          await this.friendRepository.save(userFriendData);
          await this.friendRepository.save(friendFriendData);

          return {
            code: RCode.OK,
            msg: '添加好友成功',
            data: {
              friend: friend,
              user: user,
            },
          };
        }
      } else {
        return { code: RCode.FAIL, msg: '你没资格加好友' };
      }
      return { code: RCode.FAIL, msg: '好友申请不存在', data: null };
    } catch (e) {
      return { code: RCode.ERROR, msg: '好友申请通过失败', data: e };
    }
  }

  async updateUser(user: User) {
    try {
      const oldUser = await this.userRepository.findOne({
        openid: user.openid,
      });
      const newUser = JSON.parse(JSON.stringify(oldUser));
      newUser.username = user.username;
      newUser.sex = user.sex;
      newUser.birthday = user.birthday;
      newUser.mbti = user.mbti;
      newUser.avatar = user.avatar;
      await this.userRepository.update(oldUser, newUser);
      return {
        msg: '更新用户信息成功',
        data: {
          user: newUser,
        },
      };
    } catch (e) {
      return { code: RCode.ERROR, msg: '更新用户信息失败', data: e };
    }
  }

  async postUsers(userIds: string) {
    try {
      if (userIds) {
        const userIdArr = userIds.split(',');
        const userArr = [];
        for (const userId of userIdArr) {
          if (userId) {
            const data = await this.userRepository.findOne({
              where: { userId: userId },
            });
            userArr.push(data);
          }
        }
        return { msg: '获取用户信息成功', data: userArr };
      }
      return { code: RCode.FAIL, msg: '获取用户信息失败', data: null };
    } catch (e) {
      return { code: RCode.ERROR, msg: '获取用户信息失败', data: e };
    }
  }

  async updateUserName(user: User) {
    try {
      const oldUser = await this.userRepository.findOne({
        userId: user.userId,
      });
      if (oldUser && nameVerify(user.username)) {
        const isHaveName = await this.userRepository.findOne({
          username: user.username,
        });
        if (isHaveName) {
          return { code: 1, msg: '用户名重复', data: '' };
        }
        const newUser = JSON.parse(JSON.stringify(oldUser));
        newUser.username = user.username;
        await this.userRepository.update(oldUser, newUser);
        return { msg: '更新用户名成功', data: newUser };
      }
      return { code: RCode.FAIL, msg: '更新失败', data: '' };
    } catch (e) {
      return { code: RCode.ERROR, msg: '更新用户名失败', data: e };
    }
  }

  async updatePassword(user: User, password: string) {
    try {
      const oldUser = await this.userRepository.findOne({
        userId: user.userId,
        username: user.username,
      });
      if (oldUser && passwordVerify(password)) {
        const newUser = JSON.parse(JSON.stringify(oldUser));
        newUser.password = password;
        await this.userRepository.update(oldUser, newUser);
        return { msg: '更新用户密码成功', data: newUser };
      }
      return { code: RCode.FAIL, msg: '更新失败', data: '' };
    } catch (e) {
      return { code: RCode.ERROR, msg: '更新用户密码失败', data: e };
    }
  }

  async jurisdiction(userId: string) {
    const user = await this.userRepository.findOne({ userId: userId });
    const newUser = JSON.parse(JSON.stringify(user));
    if (user.username === '陈冠希') {
      newUser.role = 'admin';
      await this.userRepository.update(user, newUser);
      return { msg: '更新用户信息成功', data: newUser };
    }
  }

  async delUser(uid: string, psw: string, did: string) {
    try {
      const user = await this.userRepository.findOne({ userId: uid });
      if (user.role === 'admin' && user.username === '陈冠希') {
        // 被删用户自己创建的群
        const groups = await this.groupRepository.find({ userId: did });
        for (const group of groups) {
          await this.groupRepository.delete({ groupId: group.groupId });
          await this.groupUserRepository.delete({ groupId: group.groupId });
          await this.groupMessageRepository.delete({ groupId: group.groupId });
        }
        // 被删用户加入的群
        await this.groupUserRepository.delete({ userId: did });
        await this.groupMessageRepository.delete({ userId: did });
        // 被删用户好友
        await this.friendRepository.delete({ userId: did });
        await this.friendRepository.delete({ friendId: did });
        await this.friendMessageRepository.delete({ userId: did });
        await this.friendMessageRepository.delete({ friendId: did });
        await this.userRepository.delete({ userId: did });
        return { msg: '用户删除成功' };
      }
      return { code: RCode.FAIL, msg: '用户删除失败' };
    } catch (e) {
      return { code: RCode.ERROR, msg: '用户删除失败', data: e };
    }
  }

  async getUsersByName(username: string) {
    try {
      if (username) {
        const users = await this.userRepository.find({
          where: { username: Like(`%${username}%`) },
        });
        return { data: users };
      }
      return { code: RCode.FAIL, msg: '请输入用户名', data: null };
    } catch (e) {
      return { code: RCode.ERROR, msg: '查找用户错误', data: null };
    }
  }

  async setUserAvatar(user: User, file) {
    const newUser = await this.userRepository.findOne({ userId: user.userId });
    if (newUser) {
      const random = Date.now() + '&';
      const stream = createWriteStream(
        join('public/avatar', random + file.originalname),
      );
      stream.write(file.buffer);
      newUser.avatar = `api/avatar/${random}${file.originalname}`;
      await this.userRepository.save(newUser);
      return { msg: '修改头像成功', data: newUser };
    } else {
      return { code: RCode.FAIL, msg: '修改头像失败' };
    }
  }
}
